package com.changxianggu.cloud.edu.tool.core;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.changxianggu.cloud.edu.tool.entity.error.*;
import com.changxianggu.cloud.edu.tool.entity.vo.*;
import com.changxianggu.cloud.edu.tool.key.ClazzKeyProperty;
import com.changxianggu.cloud.edu.tool.key.KeyProperty;
import com.changxianggu.cloud.edu.tool.key.StudentKeyProperty;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 清元优软教务系统处理
 *
 * @author liuyuantao
 */
@Slf4j
public class DataExtraCore {

    public static final String NAME_STR = "name";
    public static final String CODE_STR = "code";
    public static final String GRADE_STR = "grade";

    private KeyProperty keyProperty;

    List<String> errorList = new ArrayList<>();

    public DataExtraCore(KeyProperty keyProperty) {
        this.keyProperty = keyProperty;
    }

    /**
     * 初始化学院数据
     *
     * @param dataMap
     * @param collegeList
     * @param majorList
     * @param teacherList
     * @param clazzList
     * @param studentList
     * @return
     */
    public Map<String, Object> extractCollegeData(Map<String, Object> dataMap,
                                                  List<Map<String, Object>> collegeList,
                                                  List<Map<String, Object>> majorList,
                                                  List<Map<String, Object>> teacherList,
                                                  List<Map<String, Object>> clazzList,
                                                  List<Map<String, Object>> studentList,
                                                  boolean genCollege) {
        ExtraDataUtil extraDataUtil = new ExtraDataUtil();
        //从院系表抽取院系数据
        log.debug("从院系EXCEL提取院系数据");
        dataMap = extraDataUtil.extractCollegeData(dataMap, collegeList,
                keyProperty.getCollegeKeyProperty().getCollegeNameKey(),
                keyProperty.getCollegeKeyProperty().getCollegeCodeKey(), genCollege, "院系EXCEL");
        //从专业表抽取院系数据
        log.debug("从专业EXCEL提取院系数据");
        dataMap = extraDataUtil.extractCollegeData(dataMap, majorList,
                keyProperty.getMajorKeyProperty().getMajorCollegeNameKey(),
                keyProperty.getMajorKeyProperty().getMajorCollegeCodeKey(), genCollege, "专业EXCEL");
        //从教师表抽取院系数据
        log.debug("从教师EXCEL提取院系数据");
        dataMap = extraDataUtil.extractCollegeData(dataMap, teacherList,
                keyProperty.getTeacherKeyProperty().getTeacherCollegeNameKey(),
                keyProperty.getTeacherKeyProperty().getTeacherCollegeCodeKey(), genCollege, "教师EXCEL");
        //从班级表抽取院系数据
        log.debug("从班级EXCEL提取院系数据");
        dataMap = extraDataUtil.extractCollegeData(dataMap, clazzList,
                keyProperty.getClazzKeyProperty().getClazzCollegeNameKey(),
                keyProperty.getClazzKeyProperty().getClazzCollegeCodeKey(), genCollege, "班级EXCEL");
        //从学生表抽取院系数据
        log.debug("从学生EXCEL提取院系数据");
        dataMap = extraDataUtil.extractCollegeData(dataMap, studentList,
                keyProperty.getStudentKeyProperty().getStudentCollegeNameKey(),
                keyProperty.getStudentKeyProperty().getStudentCollegeCodeKey(), genCollege, "学生EXCEL");
        List<String> collegeExtraErrorList = extraDataUtil.getErrorList();
        //校验下名字相同,代码不同的
        log.debug("校验院系名字相同,代码不同的数据");
        Map<String, String> verifyMap = new HashMap<>(16);
        for (Object collObj : dataMap.values()) {
            CollegeVO collegeVO = (CollegeVO) collObj;
            String name = collegeVO.getName();
            String code = collegeVO.getCode();
            String tmpCode = verifyMap.get(name);
            if (tmpCode == null) {
                verifyMap.put(name, code);
            } else {
                if (!StrUtil.equalsIgnoreCase(tmpCode, code)) {
                    collegeExtraErrorList.add(StrUtil.format(CollegeError.MULTI_CODE, name));
                }
            }
        }
        verifyMap.clear();
        if (CollUtil.isNotEmpty(collegeExtraErrorList)) {
            log.debug("院系数据存在{}条错误信息提示", collegeExtraErrorList.size());
        }
        //收集错误信息
        this.errorList.addAll(collegeExtraErrorList);
        return dataMap;
    }

    /**
     * 初始化学院数据
     *
     * @param majorList
     * @param collegeMap
     * @return
     */

    public Map<String, Object> extractMajorData(Map<String, Object> dataMap,
                                                Map<String, Object> collegeMap,
                                                List<Map<String, Object>> majorList,
                                                List<Map<String, Object>> clazzList,
                                                List<Map<String, Object>> studentList,
                                                boolean genMajor) {
        ExtraDataUtil extraDataUtil = new ExtraDataUtil();
        //从专业表抽取专业数据
        log.debug("从专业EXCEL提取专业数据");
        dataMap = extraDataUtil.extractMajorData(collegeMap, dataMap, majorList,
                keyProperty.getMajorKeyProperty().getMajorNameKey(),
                keyProperty.getMajorKeyProperty().getMajorCodeKey(),
                keyProperty.getMajorKeyProperty().getMajorCollegeNameKey(),
                keyProperty.getMajorKeyProperty().getMajorCollegeCodeKey(),
                keyProperty.getMajorKeyProperty().getMajorTypeNameKey(), genMajor, "专业EXCEL");
        //从班级表抽取专业数据
        log.debug("从班级EXCEL提取专业数据");
        dataMap = extraDataUtil.extractMajorData(collegeMap, dataMap, clazzList,
                keyProperty.getClazzKeyProperty().getClazzMajorNameKey(),
                keyProperty.getClazzKeyProperty().getClazzMajorCodeKey(),
                keyProperty.getClazzKeyProperty().getClazzCollegeNameKey(),
                keyProperty.getClazzKeyProperty().getClazzCollegeCodeKey(),
                keyProperty.getClazzKeyProperty().getClazzMajorTypeNameKey(), genMajor, "班级EXCEL");
        //从学生表抽取专业数据
        log.debug("从学生EXCEL提取专业数据");
        dataMap = extraDataUtil.extractMajorData(collegeMap, dataMap, studentList,
                keyProperty.getStudentKeyProperty().getStudentMajorNameKey(),
                keyProperty.getStudentKeyProperty().getStudentMajorCodeKey(),
                keyProperty.getStudentKeyProperty().getStudentCollegeNameKey(),
                keyProperty.getStudentKeyProperty().getStudentCollegeCodeKey(),
                keyProperty.getStudentKeyProperty().getStudentMajorTypeNameKey(), genMajor, "学生EXCEL");
        List<String> collegeExtraErrorList = extraDataUtil.getErrorList();
        //校验下名字相同,代码不同的
        log.debug("校验专业名字相同,代码不同的数据");
        Map<String, String> verifyMap = new HashMap<>(64);
        for (Object majorTmpObj : dataMap.values()) {
            MajorVO majorVO = (MajorVO) majorTmpObj;
            String name = majorVO.getName();
            String code = majorVO.getCode();
            String tmpCode = verifyMap.get(name);
            if (tmpCode == null) {
                verifyMap.put(name, code);
            } else {
                if (!StrUtil.equalsIgnoreCase(tmpCode, code)) {
                    collegeExtraErrorList.add(StrUtil.format(MajorError.MULTI_CODE, name));
                }
            }
        }
        verifyMap.clear();
        if (CollUtil.isNotEmpty(collegeExtraErrorList)) {
            log.debug("专业数据存在{}条错误信息提示.", collegeExtraErrorList.size());
        }
        //收集错误信息
        errorList.addAll(collegeExtraErrorList);
        return dataMap;
    }


    public Map<String, Object> extraMajorFxData(Map<String, Object> majorMap, List<Map<String, Object>> majorFxList, List<Map<String, Object>> studentList) {
        //TODO 专业方向的数据暂时从专业表获取,不从独立的excel获取
        return null;
    }


    public Map<String, Object> extractOfficeData(Map<String, Object> dataMap,
                                                 List<Map<String, Object>> officeList,
                                                 List<Map<String, Object>> courseList,
                                                 List<Map<String, Object>> courseStuList,
                                                 Map<String, Object> collegeMap,
                                                 boolean genOffice) {
        ExtraDataUtil extraDataUtil = new ExtraDataUtil();
        //从教研室表抽取教研室数据
        log.debug("从教研室EXCEL提取教研室数据");
        dataMap = extraDataUtil.extractOfficeData(collegeMap, dataMap, officeList,
                keyProperty.getOfficeKeyProperty().getOfficeNameKey(),
                keyProperty.getOfficeKeyProperty().getOfficeCodeKey(),
                keyProperty.getOfficeKeyProperty().getOfficeCollegeNameKey(),
                keyProperty.getOfficeKeyProperty().getOfficeCollegeCodeKey(), genOffice, "教研室EXCEL");
        //从课程表抽取教研室数据
        log.debug("从课程表EXCEL提取教研室数据");
        dataMap = extraDataUtil.extractOfficeData(collegeMap, dataMap, courseList,
                keyProperty.getCourseKeyProperty().getCourseOfficeNameKey(),
                keyProperty.getCourseKeyProperty().getCourseOfficeCodeKey(),
                keyProperty.getCourseKeyProperty().getCourseCollegeNameKey(),
                keyProperty.getCourseKeyProperty().getCourseCollegeCodeKey(), genOffice, "课程EXCEL");
        //从学生选课表抽取教研室数据
        log.debug("从学生选课表EXCEL提取教研室数据");
        dataMap = extraDataUtil.extractOfficeData(collegeMap, dataMap, courseStuList,
                keyProperty.getCourseStudentKeyProperty().getCourseStuOfficeNameKey(),
                keyProperty.getCourseStudentKeyProperty().getCourseStuOfficeCodeKey(),
                keyProperty.getCourseStudentKeyProperty().getCourseStuCollegeNameKey(),
                keyProperty.getCourseStudentKeyProperty().getCourseStuCollegeCodeKey(), genOffice, "学生选课EXCEL");
        List<String> collegeExtraErrorList = extraDataUtil.getErrorList();
        //校验下名字相同,代码不同的
        log.debug("校验教研室名字相同,代码不同的数据");
        Map<String, String> verifyMap = new HashMap<>(64);
        for (Object officeTmpObj : dataMap.values()) {
            OfficeVO officeVO = (OfficeVO) officeTmpObj;
            String name = officeVO.getName();
            String code = officeVO.getCode();
            String tmpCode = verifyMap.get(name);
            if (tmpCode == null) {
                verifyMap.put(name, code);
            } else {
                if (!StrUtil.equalsIgnoreCase(tmpCode, code)) {
                    collegeExtraErrorList.add(StrUtil.format(OfficeError.MULTI_CODE, name));
                }
            }
        }
        verifyMap.clear();

        if (CollUtil.isNotEmpty(collegeExtraErrorList)) {
            log.debug("教研室数据存在{}条错误信息提示.", collegeExtraErrorList.size());
        }
        //收集错误信息
        errorList.addAll(collegeExtraErrorList);
        return dataMap;
    }


    public Map<String, Object> extractClazzData(Map<String, Object> dataMap,
                                                List<Map<String, Object>> clazzList,
                                                List<Map<String, Object>> studentList,
                                                Map<String, Object> majorMap,
                                                Map<String, Object> collegeMap,
                                                boolean genClazz) {
        ExtraDataUtil extraDataUtil = new ExtraDataUtil();
        ClazzKeyProperty clazzKeyProperty = keyProperty.getClazzKeyProperty();
        //从班级表抽取班级数据
        log.debug("从班级EXCEL提取班级数据");
        dataMap = extraDataUtil.extractClazzData(dataMap, collegeMap, majorMap, clazzList,
                clazzKeyProperty.getClazzNameKey(),
                clazzKeyProperty.getClazzCodeKey(),
                clazzKeyProperty.getClazzMajorNameKey(),
                clazzKeyProperty.getClazzMajorCodeKey(),
                clazzKeyProperty.getClazzCollegeNameKey(),
                clazzKeyProperty.getClazzCollegeCodeKey(),
                clazzKeyProperty.getClazzNumberKey(),
                clazzKeyProperty.getClazzCampusNameKey(),
                clazzKeyProperty.getClazzGradeKey(), genClazz, "班级EXCEL");
        //从班级表抽取班级数据
        log.debug("从学生EXCEL提取班级数据");
        StudentKeyProperty studentKeyProperty = keyProperty.getStudentKeyProperty();
        dataMap = extraDataUtil.extractClazzData(dataMap, collegeMap, majorMap, studentList,
                studentKeyProperty.getStudentClazzNameKey(),
                studentKeyProperty.getStudentClazzCodeKey(),
                studentKeyProperty.getStudentMajorNameKey(),
                studentKeyProperty.getStudentMajorCodeKey(),
                studentKeyProperty.getStudentCollegeNameKey(),
                studentKeyProperty.getStudentCollegeCodeKey(),
                null,
                studentKeyProperty.getStudentCampusKey(),
                studentKeyProperty.getStudentGradeKey(), genClazz, "学生EXCEL");
        List<String> collegeExtraErrorList = extraDataUtil.getErrorList();
        //校验下名字相同,代码不同的
        log.debug("校验班级名字相同,代码不同的数据");
        Map<String, String> verifyMap = new HashMap<>();
        for (Object clazzTmpObj : dataMap.values()) {
            ClazzVO clazzVO = (ClazzVO) clazzTmpObj;
            String name = clazzVO.getName();
            String code = clazzVO.getCode();
            String tmpCode = verifyMap.get(name);
            if (tmpCode == null) {
                verifyMap.put(name, code);
            } else {
                if (!StrUtil.equalsIgnoreCase(tmpCode, code)) {
                    String fxError = "班级名:[" + name + "]存在多个代码";
                    collegeExtraErrorList.add(fxError);
                }
            }
        }
        verifyMap.clear();
        if (CollUtil.isNotEmpty(collegeExtraErrorList)) {
            log.debug("班级数据存在{}条错误信息提示.", collegeExtraErrorList.size());
        }
        //收集错误信息
        errorList.addAll(collegeExtraErrorList);
        return dataMap;
    }


    public Map<String, Object> extractTeacherData(Map<String, Object> dataMap,
                                                  List<Map<String, Object>> teacherList,
                                                  Map<String, Object> collegeMap) {
        ExtraDataUtil extraDataUtil = new ExtraDataUtil();
        //从教师表抽取教师数据
        log.debug("从教师EXCEL提取教师数据");
        dataMap = extraDataUtil.extractTeacherData(collegeMap, dataMap, teacherList,
                keyProperty.getTeacherKeyProperty(), "教师EXCEL");
        List<String> collegeExtraErrorList = extraDataUtil.getErrorList();
        if (CollUtil.isNotEmpty(collegeExtraErrorList)) {
            log.debug("教师数据存在{}条错误信息提示.", collegeExtraErrorList.size());
        }
        //收集错误信息
        errorList.addAll(collegeExtraErrorList);
        return dataMap;
    }


    public Map<String, Object> extractStudentData(List<Map<String, Object>> studentList, Map<String, Object> collegeMap,
                                                  Map<String, Object> majorMap, Map<String, Object> majorFxMap, Map<String, Object> clazzMap) {
        ExtraDataUtil extraDataUtil = new ExtraDataUtil();
        //从学生表抽取学生数据
        log.debug("从学生EXCEL提取学生数据");
        Map<String, Object> studentMap = extraDataUtil.extractStudentData(collegeMap,
                majorMap, majorFxMap, clazzMap, studentList, keyProperty.getStudentKeyProperty(), "学生EXCEL");
        List<String> collegeExtraErrorList = extraDataUtil.getErrorList();
        if (CollUtil.isNotEmpty(collegeExtraErrorList)) {
            log.debug("学生数据存在{}条错误信息提示.", collegeExtraErrorList.size());
        }
        errorList.addAll(collegeExtraErrorList);
        return studentMap;
    }


    public Map<String, Object> extractCourseData(List<Map<String, Object>> courseList, Map<String, Object> collegeMap,
                                                 Map<String, Object> officeMap,
                                                 Map<String, Object> teacherMap, Map<String, Object> clazzMap,
                                                 Map<String, Object> majorMap, Map<String, Object> majorFxMap,
                                                 Map<String, Object> useCourseMap) {
        Map<String, Object> courseMap = new HashMap<>();
        //用于校验课程数据的临时map
        log.debug("从课程EXCEL提取班级上课数据");
        HashMap<String, CourseVO> verifyMap = new HashMap<>();
        ExtraDataUtil extraDataUtil = new ExtraDataUtil();
        for (Map<String, Object> dataObj : courseList) {
            String courseName = null;
            String courseCode = "";
            String courseXuCode = "";
            String collegeName = null;
            String collegeCode = null;
            String officeName = null;
            String officeCode = null;
            String teacherName = "";
            String teacherCode = "";
            String courseAttr = null;
            String courseFxName = null;
            String courseFxCode = null;
            String courseMajorName = null;
            String courseMajorCode = null;
            String courseGrade = null;

            Object nameObj = dataObj.get(keyProperty.getCourseKeyProperty().getCourseNameKey());
            Object codeObj = dataObj.get(keyProperty.getCourseKeyProperty().getCourseCodeKey());
            Object courseXuCodeObj = dataObj.get(keyProperty.getCourseKeyProperty().getCourseXuCodeKey());
            String courseCollegeNameKey = keyProperty.getCourseKeyProperty().getCourseCollegeNameKey();
            String courseCollegeCodeKey = keyProperty.getCourseKeyProperty().getCourseCollegeCodeKey();
            Object officeNameObj = dataObj.get(keyProperty.getCourseKeyProperty().getCourseOfficeNameKey());
            Object officeCodeObj = dataObj.get(keyProperty.getCourseKeyProperty().getCourseOfficeCodeKey());

            Object clazzNameObj = dataObj.get(keyProperty.getCourseKeyProperty().getCourseClazzNameKey());
            Object clazzCodeObj = dataObj.get(keyProperty.getCourseKeyProperty().getCourseClazzCodeKey());
            Object teacherNameObj = dataObj.get(keyProperty.getCourseKeyProperty().getCourseTeacherNameKey());
            Object teacherCodeObj = dataObj.get(keyProperty.getCourseKeyProperty().getCourseTeacherCodeKey());
            Object courseAttrObj = dataObj.get(keyProperty.getCourseKeyProperty().getCourseAttrKey());

            Object majorNameObj = dataObj.get(keyProperty.getCourseKeyProperty().getCourseMajorNameKey());
            Object majorCodeObj = dataObj.get(keyProperty.getCourseKeyProperty().getCourseMajorCodeKey());


            Object gradeObj = dataObj.get(keyProperty.getCourseKeyProperty().getCourseGrade());

            Object fxNameObj = dataObj.get(keyProperty.getCourseKeyProperty().getCourseMajorFxNameKey());
            Object fxCodeObj = dataObj.get(keyProperty.getCourseKeyProperty().getCourseMajorFxCodeKey());
            //课程名和课程代码解析正则
            String courseNameCodeRegStr = keyProperty.getCourseKeyProperty().getCourseNameCodeRegStr();
            boolean hasError = false;
            //检查课程的名字和代码是否在一起
            CourseVO courseVO = initCourseNameAndCode(courseNameCodeRegStr, nameObj, codeObj, "");
            if (courseVO == null) {
                continue;
            } else {
                courseName = courseVO.getName();
                courseCode = courseVO.getCode();
            }
            String useCollegeName = null;
            String useCollegeCode = null;
            String useOfficeName = null;
            String useOfficeCode = null;
            if (courseAttrObj != null) {
                courseAttr = StrUtil.removeAll(courseAttrObj.toString(), " ");
            } else {
                errorList.add(courseName + "的课程性质未填写.");
            }
            if (MapUtil.isNotEmpty(useCourseMap)) {
                Object useCourseObj = useCourseMap.get(courseCode);
                if (useCourseObj != null) {
                    CourseVO useCourse = (CourseVO) useCourseObj;
                    String useCourseName = useCourse.getName();
                    if (!StrUtil.equalsIgnoreCase(useCourseName, courseName)) {
                        errorList.add("课程代码[" + courseCode + "]的课程名[" + courseName + "]与现有的同样课程代码的课程名[" + useCourseName + "]不一致.");
                    }
                    String courseAttrOld = useCourse.getCourseAttr();
                    if (!StrUtil.equalsIgnoreCase(courseAttrOld, courseAttr)) {
                        errorList.add("课程[" + courseName + "],课程代码[" + courseCode + "]的课程性质已平台已开设课程不一致.");
                    }
                    useCollegeName = useCourse.getCollegeName();
                    useCollegeCode = useCourse.getCollegeCode();
                    useOfficeName = useCourse.getOfficeName();
                    useOfficeCode = useCourse.getOfficeCode();
                }
            }
            if (StrUtil.isBlank(courseName) || StrUtil.isBlank(courseCode)) {
                hasError = true;
                errorList.add("课程解析错误,课程名和课程代码不存在.");
            }
            if (StrUtil.isBlank(courseName) || StrUtil.isBlank(courseCode)) {
                errorList.add("课程解析错误,课程名和课程代码不存在.");
            }
            if (courseXuCodeObj != null) {
                courseXuCode = StrUtil.removeAll(courseXuCodeObj.toString(), " ");
            }
            //处理专业
            if (majorNameObj != null) {
                courseMajorName = majorNameObj.toString().trim();
            }
            if (majorCodeObj != null) {
                courseMajorCode = majorCodeObj.toString().trim();
            }
            //如果专业名字存在,则使用名字比对
            if (StrUtil.isNotBlank(courseMajorName)) {
                boolean findMajor = false;
                for (Object obj : majorMap.values()) {
                    MajorVO majorVO = (MajorVO) obj;
                    String majorVOName = majorVO.getName();
                    if (StrUtil.equalsIgnoreCase(majorVOName, courseMajorName)) {
                        //找到了专业代码
                        String courseCodeTmp = majorVO.getCode();
                        if (StrUtil.isNotBlank(courseMajorCode)) {
                            //专业方向代码一直
                            if (StrUtil.equalsIgnoreCase(courseMajorCode, courseCodeTmp)) {
                                courseMajorCode = courseCodeTmp;
                                findMajor = true;
                                break;
                            }
                        } else {
                            courseMajorCode = courseCodeTmp;
                            findMajor = true;
                            break;
                        }
                    }
                }
                if (!findMajor) {
                    errorList.add("课程的专业名[" + courseMajorName + "]在专业表未找到.");
                    continue;
                }
            } else if (StrUtil.isNotBlank(courseMajorCode)) {
                //名字不存在,若代码存在,则使用代码
                Object objMajor = majorMap.get(courseMajorCode);
                if (objMajor != null) {
                    MajorVO majorVO = (MajorVO) objMajor;
                    courseMajorName = majorVO.getName();
                } else {
                    errorList.add("课程的专业代码[" + courseMajorCode + "]在专业表未找到.");
                    continue;
                }
            }
            //处理专业方向
            if (fxNameObj != null) {
                courseFxName = fxNameObj.toString().trim();
            }
            if (fxCodeObj != null) {
                courseFxCode = fxCodeObj.toString().trim();
            }
            //如果专业方向名字存在,则使用名字比对
            if (StrUtil.isNotBlank(courseFxName)) {
                boolean findFx = false;
                for (Object obj : majorFxMap.values()) {
                    MajorFxVO majorFxVO = (MajorFxVO) obj;
                    String majorFxVOName = majorFxVO.getName();
                    if (StrUtil.equalsIgnoreCase(majorFxVOName, courseFxName)) {
                        //找到了专业代码
                        String courseFxCodeTmp = majorFxVO.getCode();
                        if (StrUtil.isNotBlank(courseFxCode)) {
                            //专业方向代码一直
                            if (StrUtil.equalsIgnoreCase(courseFxCode, courseFxCodeTmp)) {
                                courseFxCode = courseFxCodeTmp;
                                findFx = true;
                                break;
                            }
                        } else {
                            courseFxCode = courseFxCodeTmp;
                            findFx = true;
                            break;
                        }
                    }
                }
                if (!findFx) {
                    errorList.add("课程的专业方向名[" + courseFxName + "]在专业表未找到.");
                    continue;
                }
            } else if (StrUtil.isNotBlank(courseFxCode)) {
                //名字不存在,若代码存在,则使用代码
                Object objMajorFx = majorFxMap.get(courseFxCode);
                if (objMajorFx != null) {
                    MajorFxVO majorFxVO = (MajorFxVO) objMajorFx;
                    courseFxName = majorFxVO.getName();
                } else {
                    errorList.add("课程的专业方向代码[" + courseFxCode + "]在专业表未找到.");
                    continue;
                }
            }
            if (gradeObj != null) {
                courseGrade = gradeObj.toString().trim();
            }
            //处理开课学院
            CollegeVO extraCollege = extraDataUtil.extraCollegeNameCode(collegeMap, dataObj, courseCollegeNameKey, courseCollegeCodeKey);
            String collegeErrorMessage = extraCollege.getErrorMessage();
            if (collegeErrorMessage == null) {
                //说明提取到了院系的数据
                collegeName = extraCollege.getName();
                collegeCode = extraCollege.getCode();
            } else {
                if (StrUtil.equals("1", collegeErrorMessage)) {
                    //没有填写院系名和院系代码
                    String errorName = courseName == null ? courseCode : courseName;
                    errorList.add(StrUtil.format(ClazzError.NO_COLLEGE_NAME_CODE, "课程表", errorName));
                } else {
                    errorList.add(StrUtil.format(collegeErrorMessage, "课程表", "课程"));
                }
                continue;
            }
            if (officeNameObj != null) {
                String errorMsg = null;
                officeName = officeNameObj.toString().trim();
                for (Object officeObj : officeMap.values()) {
                    OfficeVO officeVO = (OfficeVO) officeObj;
                    String officeVOName = officeVO.getName();
                    //找到了
                    if (StrUtil.equalsIgnoreCase(officeVOName, officeName)) {
                        officeCode = officeVO.getCode();
                        String officeCollegeCode = officeVO.getCollegeCode();
                        if (!StrUtil.equalsIgnoreCase(collegeCode, officeCollegeCode)) {
                            errorMsg = "课程表里存在课程[" + courseName + "]的教研室[" + officeName + "]的所属院系代码与开课学院代码不一致.";
                        }
                        break;
                    }
                }
                if (StrUtil.isBlank(officeCode)) {
                    errorMsg = "课程表里存在课程[" + courseName + "]的教研室[" + officeName + "]未找到对应的教研室代码.";
                }
                if (StrUtil.isNotBlank(errorMsg)) {
                    errorList.add(errorMsg);
                }
            }
            if (officeCodeObj != null) {
                officeCode = officeCodeObj.toString();
                Object officeObj = officeMap.get(officeCode);
                String errorMsg = null;
                if (officeObj == null) {
                    errorMsg = "课程表里存在课程[" + courseName + "]的教研室代码[" + officeCode + "]的教研室不存在.";
                } else {
                    OfficeVO officeVO = (OfficeVO) officeObj;
                    String officeVOName = officeVO.getName();
                    if (!StrUtil.equalsIgnoreCase(officeName, officeVOName)) {
                        errorMsg = "课程表里存在课程[" + courseName + "]的教研室代码[" + officeCode + "]的名字与已存在的不一致.";
                    }
                    String officeVOCollegeCode = officeVO.getCollegeCode();
                    if (!StrUtil.equalsIgnoreCase(collegeCode, officeVOCollegeCode)) {
                        errorMsg = "课程表里存在课程[" + courseName + "]的教研室代码[" + officeCode + "]的所属院系代码与开课学院代码不一致.";
                    }
                }
                if (StrUtil.isNotBlank(errorMsg)) {
                    errorList.add(errorMsg);
                }
            }

            //开始处理教师
            String courseTeacherRegStr = keyProperty.getCourseKeyProperty().getCourseTeacherRegStr();
            if (StrUtil.isNotBlank(courseTeacherRegStr)) {
                if (teacherNameObj != null) {
                    TeacherVO teacherVO = initTeacherSplit(teacherNameObj.toString());
                    if (teacherVO != null) {
                        teacherName = teacherVO.getName();
                        teacherCode = teacherVO.getCode();
                    }
                }
            } else {
                if (teacherNameObj != null) {
                    teacherName = teacherNameObj.toString().trim();

                }
                if (teacherCodeObj != null) {
                    teacherCode = teacherCodeObj.toString().trim();
                }
            }
            boolean findTeacher = false;
            if (StrUtil.isNotBlank(teacherCode)) {
                //存在工号,使用工号去查找,顺便检查名字是否正确
                Object objTea = teacherMap.get(teacherCode);
                if (objTea != null) {
                    findTeacher = true;
                    TeacherVO teacherVO = (TeacherVO) objTea;
                    String tName = teacherVO.getName();
                    if (StrUtil.isNotBlank(teacherName)) {
                        if (!StrUtil.equalsIgnoreCase(teacherName, tName)) {
                            errorList.add("课程[" + courseName + "]任课教师工号[" + teacherCode + "]存在多个名字错误.");
                        }
                    } else {
                        teacherName = teacherVO.getName();
                    }
                }
            } else {
                if (StrUtil.isNotBlank(teacherName)) {
                    for (Object teacherObj : teacherMap.values()) {
                        TeacherVO teacherVO = (TeacherVO) teacherObj;
                        String tName = teacherVO.getName();
                        if (StrUtil.equalsIgnoreCase(tName, teacherName)) {
                            findTeacher = true;
                            break;
                        }
                    }
                }
            }
            if (!findTeacher) {
                if (StrUtil.isNotBlank(teacherName) || StrUtil.isNotBlank(teacherCode)) {
                    errorList.add("课程[" + courseName + "]任课教师[" + teacherName + ":" + teacherCode + "]未在教师Excel找到.");
                }
            }
            //校验平台已经存在的课程的开课学院和教研室
            if (StrUtil.isNotBlank(useCollegeCode)) {
                if (!StrUtil.equalsIgnoreCase(useCollegeCode, collegeCode)) {
                    errorList.add("课程[" + courseName + "]的开课学院代码[" + collegeCode + "]与平台现有的同样课程代码的开课学院代码[" + useCollegeCode + "]不一致.");
                }
            }
            if (StrUtil.isNotBlank(useCollegeName)) {
                if (!StrUtil.equalsIgnoreCase(useCollegeName, collegeName)) {
                    errorList.add("课程[" + courseName + "]的开课学院[" + collegeName + "]与平台现有的同样课程代码的开课学院[" + useCollegeName + "]不一致.");
                }
            }
            if (StrUtil.isNotBlank(useOfficeName)) {
                if (!StrUtil.equalsIgnoreCase(useOfficeName, officeName)) {
                    errorList.add("课程[" + courseName + "]的开课教研室[" + officeName + "]与平台现有的同样课程代码的开课教研室[" + useOfficeName + "]不一致.");
                }
            }
            if (StrUtil.isNotBlank(useOfficeCode)) {
                if (!StrUtil.equalsIgnoreCase(useOfficeCode, officeCode)) {
                    errorList.add("课程[" + courseName + "]的开课教研室代码[" + officeCode + "]与平台现有的同样课程代码的开课教研室代码[" + useOfficeCode + "]不一致.");
                }
            }
            //处理班级
            String uniqKey = courseCode + "_" + courseXuCode + "_" + courseFxName + "_" + teacherCode;
            courseVO = new CourseVO();
            courseVO.setName(courseName);
            courseVO.setCode(courseCode);
            courseVO.setXuCode(courseXuCode);
            courseVO.setCollegeName(collegeName);
            courseVO.setCollegeCode(collegeCode);
            courseVO.setOfficeName(officeName);
            courseVO.setOfficeCode(officeCode);
            courseVO.setTeacherName(teacherName);
            courseVO.setTeacherCode(teacherCode);
            courseVO.setCourseAttr(courseAttr);
            courseVO.setMajorFxName(courseFxName);
            courseVO.setMajorFxCode(courseFxCode);
            //校验一下数据
            CourseVO verifyCourseVO = verifyMap.get(courseCode);
            if (verifyCourseVO == null) {
                verifyMap.put(courseCode, courseVO);
            } else {
                String courseError = verifyCourseMap(verifyMap, courseVO);
                if (StrUtil.isNotBlank(courseError)) {
                    errorList.add(courseError);
                }
            }
            Object o = courseMap.get(uniqKey);
            if (o != null) {
                courseVO = (CourseVO) o;
                List<String> allClazzNameList = courseVO.getClazzNameList();
                List<String> extraClazzNameList = extraClazzNameList(clazzNameObj, clazzCodeObj, courseMajorCode, courseGrade, clazzMap);
                if (CollUtil.isNotEmpty(extraClazzNameList)) {
                    allClazzNameList.addAll(extraClazzNameList);
                }
                courseVO.setClazzNameList(allClazzNameList);
                courseVO.setClazzName(StrUtil.join(",", allClazzNameList));
                verifyMap.put(courseCode, courseVO);
                courseMap.put(uniqKey, courseVO);
            } else {
                List<String> extraClazzNameList = extraClazzNameList(clazzNameObj, clazzCodeObj, courseMajorCode, courseGrade, clazzMap);
                courseVO.setClazzNameList(extraClazzNameList);
                courseVO.setClazzName(StrUtil.join(",", extraClazzNameList));
                verifyMap.put(courseCode, courseVO);
                courseMap.put(uniqKey, courseVO);
            }
        }
        return courseMap;
    }

    public List<CourseStudentVO> extractCourseStudentData(List<Map<String, Object>> courseStudentList,
                                                          Map<String, Object> collegeMap, Map<String, Object> officeMap,
                                                          Map<String, Object> teacherMap, Map<String, Object> clazzMap,
                                                          Map<String, Object> useCourseMap) {
        Map<String, Integer> courseStudentMap = new HashMap<>();
        List<CourseStudentVO> courseStudentVOList = new ArrayList<>();
        //用于校验课程数据的临时map
        log.debug("从学生选择EXCEL提取学生上课数据");
        HashMap<String, CourseVO> verifyMap = new HashMap<>();
        ExtraDataUtil extraDataUtil = new ExtraDataUtil();
        String excelName = "学生选修课程表";
        for (Map<String, Object> dataObj : courseStudentList) {
            String courseName = null;
            String courseCode = null;
            String courseXuCode = "";
            String collegeName = null;
            String collegeCode = null;
            String officeName = "";
            String officeCode = "";
            String teacherName = "";
            String teacherCode = "";
            String courseAttr = "";
            String clazzName = "";
            String clazzCode = "";
            String studentName = "";
            String studentCode = "";
            Object nameObj = dataObj.get(keyProperty.getCourseStudentKeyProperty().getCourseStuNameKey());
            Object codeObj = dataObj.get(keyProperty.getCourseStudentKeyProperty().getCourseStuCodeKey());
            Object courseXuCodeObj = dataObj.get(keyProperty.getCourseStudentKeyProperty().getCourseStuXuCodeKey());
            Object officeNameObj = dataObj.get(keyProperty.getCourseStudentKeyProperty().getCourseStuOfficeNameKey());
            Object officeCodeObj = dataObj.get(keyProperty.getCourseStudentKeyProperty().getCourseStuOfficeCodeKey());

            Object clazzNameObj = dataObj.get(keyProperty.getCourseStudentKeyProperty().getCourseStuClazzNameKey());
            Object clazzCodeObj = dataObj.get(keyProperty.getCourseStudentKeyProperty().getCourseStuClazzCodeKey());
            Object teacherNameObj = dataObj.get(keyProperty.getCourseStudentKeyProperty().getCourseStuTeacherNameKey());
            Object teacherCodeObj = dataObj.get(keyProperty.getCourseStudentKeyProperty().getCourseStuTeacherCodeKey());
            Object courseAttrObj = dataObj.get(keyProperty.getCourseStudentKeyProperty().getCourseStuAttrKey());

            //课程名和课程代码解析正则
            String courseNameCodeRegStr = keyProperty.getCourseStudentKeyProperty().getCourseStuCourseNameCodeReg();
            String clearCourseNameRegStr = keyProperty.getCourseStudentKeyProperty().getCourseStuClearCourseNameReg();
            Object studentNameObj = dataObj.get(keyProperty.getCourseStudentKeyProperty().getCourseStuStudentName());
            Object studentCodeObj = dataObj.get(keyProperty.getCourseStudentKeyProperty().getCourseStuStudentCode());
            boolean hasError = false;
            //检查课程的名字和代码是否在一起
            CourseVO courseVO = initCourseNameAndCode(courseNameCodeRegStr, nameObj, codeObj, clearCourseNameRegStr);
            if (courseVO == null) {
                continue;
            } else {
                courseName = courseVO.getName();
                courseCode = courseVO.getCode();
            }
            String useCollegeName = null;
            String useCollegeCode = null;
            String useOfficeName = null;
            String useOfficeCode = null;
            if (courseAttrObj != null) {
                courseAttr = StrUtil.trim(courseAttrObj.toString());
            }
            if (MapUtil.isNotEmpty(useCourseMap)) {
                Object useCourseObj = useCourseMap.get(courseCode);
                if (useCourseObj != null) {
                    CourseVO useCourse = (CourseVO) useCourseObj;
                    String useCourseName = useCourse.getName();
                    if (!StrUtil.equalsIgnoreCase(useCourseName, courseName)) {
                        errorList.add("课程代码[" + courseCode + "]的课程名[" + courseName + "]与现有的同样课程代码的课程名[" + useCourseName + "]不一致.");
                    }
                    String courseAttrOld = useCourse.getCourseAttr();
                    if (!StrUtil.equalsIgnoreCase(courseAttrOld, courseAttr)) {
                        errorList.add("课程["+courseName + "],课程代码[" + courseCode + "]的课程性质已平台已开设课程不一致.");
                    }
                    useCollegeName = useCourse.getCollegeName();
                    useCollegeCode = useCourse.getCollegeCode();
                    useOfficeName = useCourse.getOfficeName();
                    useOfficeCode = useCourse.getOfficeCode();
                }
            }
            if (StrUtil.isBlank(courseName) || StrUtil.isBlank(courseCode)) {
                hasError = true;
                errorList.add("课程解析错误,课程名和课程代码不存在.");
            }

            if (courseXuCodeObj != null) {
                courseXuCode = StrUtil.trim(courseXuCodeObj.toString());
            }
            //处理开课学院
            CollegeVO extraCollegeVO = extraDataUtil.extraCollegeNameCode(collegeMap, dataObj,
                    keyProperty.getCourseStudentKeyProperty().getCourseStuCollegeNameKey(),
                    keyProperty.getCourseStudentKeyProperty().getCourseStuCollegeCodeKey());
            String collegeVOErrorMessage = extraCollegeVO.getErrorMessage();
            if (collegeVOErrorMessage == null) {
                //说明提取到了院系的数据
                collegeName = extraCollegeVO.getName();
                collegeCode = extraCollegeVO.getCode();
            } else {
                if (StrUtil.equals("1", collegeVOErrorMessage)) {
                    //没有填写院系名和院系代码
                    String errorName = courseName == null ? courseCode : courseName;
                    errorList.add(StrUtil.format(CourseStuError.NO_COLLEGE_NAME_CODE, excelName, errorName));
                } else {
                    errorList.add(StrUtil.format(collegeVOErrorMessage, excelName, "课程"));
                }
            }
            //开始处理教研室
            if (officeNameObj != null) {
                String errorMsg = null;
                officeName = officeNameObj.toString().trim();
                for (Object officeObj : officeMap.values()) {
                    OfficeVO officeVO = (OfficeVO) officeObj;
                    String officeVOName = officeVO.getName();
                    //找到了
                    if (StrUtil.equalsIgnoreCase(officeVOName, officeName)) {
                        officeCode = officeVO.getCode();
                        String officeCollegeCode = officeVO.getCollegeCode();
                        if (!StrUtil.equalsIgnoreCase(collegeCode, officeCollegeCode)) {
                            errorMsg = "课程表里存在课程[" + courseName + "]的教研室[" + officeName + "]的所属院系代码与开课学院代码不一致.";
                        }
                        break;
                    }
                }
                if (StrUtil.isBlank(officeCode)) {
                    errorMsg = "课程表里存在课程[" + courseName + "]的教研室[" + officeName + "]未找到对应的教研室代码.";
                }
                if (StrUtil.isNotBlank(errorMsg)) {
                    hasError = true;
                    errorList.add(errorMsg);
                }
            }
            if (officeCodeObj != null) {
                officeCode = officeCodeObj.toString();
                Object officeObj = officeMap.get(officeCode);
                String errorMsg = null;
                if (officeObj == null) {
                    errorMsg = "课程表里存在课程[" + courseName + "]的教研室代码[" + officeCode + "]的教研室不存在.";
                } else {
                    OfficeVO officeVO = (OfficeVO) officeObj;
                    String officeVOName = officeVO.getName();
                    if (!StrUtil.equalsIgnoreCase(officeName, officeVOName)) {
                        errorMsg = "课程表里存在课程[" + courseName + "]的教研室代码[" + officeCode + "]的名字与已存在的不一致.";
                    }
                    String officeVOCollegeCode = officeVO.getCollegeCode();
                    if (!StrUtil.equalsIgnoreCase(collegeCode, officeVOCollegeCode)) {
                        errorMsg = "课程表里存在课程[" + courseName + "]的教研室代码[" + officeCode + "]的所属院系代码与开课学院代码不一致.";
                    }
                }
                if (StrUtil.isNotBlank(errorMsg)) {
                    hasError = true;
                    errorList.add(errorMsg);
                }
            }

            //开始处理教师
            String courseTeacherRegStr = keyProperty.getCourseKeyProperty().getCourseTeacherRegStr();
            if (StrUtil.isNotBlank(courseTeacherRegStr)) {
                if (teacherNameObj != null) {
                    TeacherVO teacherVO = initTeacherSplit(teacherNameObj.toString());
                    if (teacherVO != null) {
                        teacherName = teacherVO.getName();
                        teacherCode = teacherVO.getCode();
                    }
                }
            } else {
                if (teacherNameObj != null) {
                    teacherName = teacherNameObj.toString().trim();

                }
                if (teacherCodeObj != null) {
                    teacherCode = teacherCodeObj.toString().trim();
                }
            }
            boolean findTeacher = false;
            if (StrUtil.isNotBlank(teacherName)) {
                for (Object teacherObj : teacherMap.values()) {
                    TeacherVO teacherVO = (TeacherVO) teacherObj;
                    String tname = teacherVO.getName();
                    if (StrUtil.equalsIgnoreCase(tname, teacherName)) {
                        findTeacher = true;
                        break;
                    }
                }
                if (!findTeacher) {
                    hasError = true;
                    errorList.add("课程[" + courseName + "]任课教师[" + teacherName + "]未在教师Excel找到.");
                }
            }
            if (StrUtil.isNotBlank(teacherCode)) {
                Object objTea = teacherMap.get(teacherCode);
                if (objTea != null) {
                    findTeacher = true;
                    TeacherVO teacherVO = (TeacherVO) objTea;
                    String tname = teacherVO.getName();
                    if (StrUtil.isNotBlank(teacherName)) {
                        if (!StrUtil.equalsIgnoreCase(teacherName, tname)) {
                            hasError = true;
                            errorList.add("课程[" + courseName + "]任课教师[" + teacherName + "]存在多个代码错误.");
                        }
                    } else {
                        teacherName = teacherVO.getName();
                    }
                }
                if (!findTeacher) {
                    hasError = true;
                    errorList.add("课程[" + courseName + "]任课教师[" + teacherName + "]未在教师Excel找到.");
                }
            }
            //处理班级
            if (clazzNameObj != null) {
                String errorMsg = null;
                clazzName = clazzNameObj.toString().trim();
                for (Object clazzObj : clazzMap.values()) {
                    ClazzVO clazzVO = (ClazzVO) clazzObj;
                    String clazzVOName = clazzVO.getName();
                    //找到了
                    if (StrUtil.equalsIgnoreCase(clazzVOName, clazzName)) {
                        clazzCode = clazzVO.getCode();
                        break;
                    }
                }
                if (StrUtil.isBlank(clazzCode)) {
                    errorMsg = "课程表里存在课程[" + courseName + "]的班级[" + clazzName + "]未找到对应的班级代码.";
                }
                if (StrUtil.isNotBlank(errorMsg)) {
                    hasError = true;
                    errorList.add(errorMsg);
                }
            }
            if (clazzCodeObj != null) {
                String tmpClazzCode = clazzCodeObj.toString();
                Object clazzObj = clazzMap.get(tmpClazzCode);
                String errorMsg = null;
                if (clazzObj == null) {
                    errorMsg = "课程表里存在课程[" + courseName + "]的班级代码[" + tmpClazzCode + "]的班级不存在.";
                } else {
                    ClazzVO clazzVO = (ClazzVO) clazzObj;
                    String clazzVOName = clazzVO.getName();
                    if (!StrUtil.equalsIgnoreCase(clazzName, clazzVOName)) {
                        errorMsg = "课程表里存在课程[" + courseName + "]的班级代码[" + tmpClazzCode + "]的名字与已存在的不一致.";
                    }
                }
                if (StrUtil.isNotBlank(errorMsg)) {
                    hasError = true;
                    errorList.add(errorMsg);
                }
            }
            if (studentNameObj != null) {
                studentName = StrUtil.trim(studentNameObj.toString());
                if (StrUtil.isBlank(studentName)) {
                    String errorMsg = "课程表里存在课程[" + courseName + "]没填学生名";
                    hasError = true;
                    errorList.add(errorMsg);
                }
            }
            if (studentCodeObj != null) {
                studentCode = StrUtil.trim(studentCodeObj.toString());
                if (StrUtil.isBlank(studentCode)) {
                    String errorMsg = "课程表里存在课程[" + courseName + "]没填学号";
                    hasError = true;
                    errorList.add(errorMsg);
                }
            }
            //校验平台已经存在的课程的开课学院和教研室
            if (StrUtil.isNotBlank(useCollegeCode)) {
                if (!StrUtil.equalsIgnoreCase(useCollegeCode, collegeCode)) {
                    errorList.add("课程[" + courseName + "]的开课学院代码[" + collegeCode + "]与平台现有的同样课程代码的开课学院代码[" + useCollegeCode + "]不一致.");
                }
            }
            if (StrUtil.isNotBlank(useCollegeName)) {
                if (!StrUtil.equalsIgnoreCase(useCollegeName, collegeName)) {
                    errorList.add("课程[" + courseName + "]的开课学院[" + collegeName + "]与平台现有的同样课程代码的开课学院[" + useCollegeName + "]不一致.");
                }
            }
            if (StrUtil.isNotBlank(useOfficeName)) {
                if (!StrUtil.equalsIgnoreCase(useOfficeName, officeName)) {
                    errorList.add("课程[" + courseName + "]的开课教研室[" + officeName + "]与平台现有的同样课程代码的开课教研室[" + useOfficeName + "]不一致.");
                }
            }
            if (StrUtil.isNotBlank(useOfficeCode)) {
                if (!StrUtil.equalsIgnoreCase(useOfficeCode, officeCode)) {
                    errorList.add("课程[" + courseName + "]的开课教研室代码[" + officeCode + "]与平台现有的同样课程代码的开课教研室代码[" + useOfficeCode + "]不一致.");
                }
            }
            if (!hasError) {
                String uniqKey = courseCode + courseXuCode + studentCode;
                Integer hasInt = courseStudentMap.get(uniqKey);
                if (hasInt == null) {
                    CourseStudentVO courseStudentVO = new CourseStudentVO();
                    courseStudentVO.setName(courseName);
                    courseStudentVO.setCode(courseCode);
                    courseStudentVO.setCollegeName(collegeName);
                    courseStudentVO.setCollegeCode(collegeCode);
                    courseStudentVO.setOfficeName(officeName);
                    courseStudentVO.setOfficeCode(officeCode);
                    courseStudentVO.setClazzName(clazzName);
                    courseStudentVO.setClazzCode(clazzCode);
                    courseStudentVO.setStudentName(studentName);
                    courseStudentVO.setStudentCode(studentCode);
                    courseStudentVO.setTeacherName(teacherName);
                    courseStudentVO.setTeacherCode(teacherCode);
                    if (StrUtil.isBlank(courseAttr)) {
                        courseAttr = "选修";
                    }
                    courseStudentVO.setCourseAttr(courseAttr);
                    courseStudentVOList.add(courseStudentVO);
                } else {
                    String errorMsg = "存在相同学号[" + studentCode + "]选择同一门课程[" + courseName + "]的错误";
                    errorList.add(errorMsg);
                }
            }
        }
        return courseStudentVOList;
    }

    /**
     * 提取课程名称和课程代码
     *
     * @param courseNameCodeRegStr
     * @param nameObj
     * @param codeObj
     * @return
     */
    public CourseVO initCourseNameAndCode(String courseNameCodeRegStr, Object nameObj, Object codeObj, String clearNameRegStr) {
        CourseVO courseVO = null;
        if (StrUtil.isNotBlank(courseNameCodeRegStr)) {
            if (nameObj != null) {
                courseVO = initCourseSplit(nameObj.toString(), courseNameCodeRegStr);
                if (courseVO != null) {
                    courseVO.setName(clearCourseName(courseVO.getName(), clearNameRegStr));
                    return courseVO;
                }
            }
            if (codeObj != null) {
                courseVO = initCourseSplit(codeObj.toString(), courseNameCodeRegStr);
                if (courseVO != null) {
                    courseVO.setName(clearCourseName(courseVO.getName(), clearNameRegStr));
                    return courseVO;
                }
            }
        } else {
            if (nameObj == null) {
                return null;
            } else {
                courseVO = new CourseVO();
                String clearCourseName = clearCourseName(nameObj.toString(), clearNameRegStr);
                courseVO.setName(clearCourseName);
            }
            if (codeObj == null) {
                return null;
            } else {
                courseVO.setCode(codeObj.toString());

            }
        }
        return courseVO;
    }

    /**
     * 清楚课程名的正则表达式
     *
     * @param courseName
     * @param clearReg
     * @return
     */
    public String clearCourseName(String courseName, String clearReg) {
        if (StrUtil.isNotBlank(clearReg)) {
            courseName = courseName.replaceAll(clearReg, "");
        }
        return courseName.trim();
    }


    public String verifyCourseMap(Map<String, CourseVO> verifyMap, CourseVO courseVO) {
        String errorMsg = null;
        String courseCode = courseVO.getCode();
        String courseVOName = courseVO.getName();
        String collegeCode = courseVO.getCollegeCode();
        String officeCode = courseVO.getOfficeCode();
        String courseAttr = courseVO.getCourseAttr();
        CourseVO verifyCourseVO = verifyMap.get(courseCode);
        String verifyCourseVOName = verifyCourseVO.getName();
        String verifyCourseVOCollegeCode = verifyCourseVO.getCollegeCode();
        String verifyCourseVOOfficeCode = verifyCourseVO.getOfficeCode();
        String verifyCourseAttr = verifyCourseVO.getCourseAttr();
        if (!StrUtil.equalsIgnoreCase(verifyCourseVOName, courseVOName)) {
            errorMsg = "课程代码[" + courseCode + "]的存在多个课程名.";
            return errorMsg;
        }
        if (!StrUtil.equalsIgnoreCase(verifyCourseVOCollegeCode, collegeCode)) {
            errorMsg = "课程名:[" + courseVOName + "]课程代码[" + courseCode + "]的开课学院不一致.";
            return errorMsg;
        }
        if (!StrUtil.equalsIgnoreCase(verifyCourseAttr, courseAttr)) {
            errorMsg = "课程[" + courseVOName + "],课程代码[" + courseCode + "]的课程性质不一致.";
            return errorMsg;
        }
        if (StrUtil.isNotBlank(officeCode)) {
            if (!StrUtil.equalsIgnoreCase(verifyCourseVOOfficeCode, officeCode)) {
                errorMsg = "课程名:[" + courseVOName + "]课程代码[" + courseCode + "]的开课教研室不一致.";
                return errorMsg;
            }
        }
        return errorMsg;
    }

    /**
     * 提取班级名称
     *
     * @param clazzNameObj
     * @param clazzCodeObj
     * @param clazzMap
     * @return
     */
    public List<String> extraClazzNameList(Object clazzNameObj, Object clazzCodeObj, String courseMajorCode,
                                           String courseGrade, Map<String, Object> clazzMap) {
        List<String> clazzNameList = new ArrayList<>();
        if (clazzNameObj != null) {
            clazzNameList = splitClazz(clazzNameObj.toString().trim());
            if (CollUtil.isNotEmpty(clazzNameList)) {
                CopyOnWriteArrayList<String> copyOnWriteArrayList = new CopyOnWriteArrayList<String>(clazzNameList);
                String courseClazzRubbishStr = keyProperty.getCourseKeyProperty().getCourseClazzRubbishStr();
                if (StrUtil.isNotBlank(courseClazzRubbishStr)) {
                    String[] splitRubbish = courseClazzRubbishStr.split(",");
                    if (splitRubbish != null && splitRubbish.length > 0) {
                        for (int i = 0; i < splitRubbish.length; i++) {
                            String rubbishStr = splitRubbish[i];
                            copyOnWriteArrayList.remove(rubbishStr);
                        }
                    }
                }
                for (String clazzName : copyOnWriteArrayList) {
                    String clazzCode = null;
                    for (Object clazzObj : clazzMap.values()) {
                        ClazzVO clazzVO = (ClazzVO) clazzObj;
                        String tmpName = clazzVO.getName();
                        if (StrUtil.equalsIgnoreCase(clazzName, tmpName)) {
                            clazzCode = clazzVO.getCode();
                            break;
                        }
                    }
                    if (clazzCode == null) {
                        if (StrUtil.isNotBlank(clazzName)) {
                            errorList.add("课程表里班级名[" + clazzName + "]未找到关联数据.");
                        }
                        copyOnWriteArrayList.remove(clazzName);
                    }
                }
                clazzNameList = CollUtil.newArrayList(copyOnWriteArrayList);
            }
        } else {
            if (clazzCodeObj != null) {
                List<String> clazzCodeList = splitClazz(clazzCodeObj.toString().trim());
                clazzNameList = new ArrayList<>();
                if (CollUtil.isNotEmpty(clazzCodeList)) {
                    CopyOnWriteArrayList<String> copyOnWriteArrayList = new CopyOnWriteArrayList<String>(clazzCodeList);
                    String courseClazzRubbishStr = keyProperty.getCourseKeyProperty().getCourseClazzRubbishStr();
                    if (StrUtil.isNotBlank(courseClazzRubbishStr)) {
                        copyOnWriteArrayList.remove("*");
                    }
                    for (String clazzCode : copyOnWriteArrayList) {
                        Object objClazz = clazzMap.get(clazzCode);
                        if (objClazz == null) {
                            errorList.add("课程表里班级代码[" + clazzCode + "]未找到关联数据.");
                            copyOnWriteArrayList.remove(clazzCode);
                        } else {
                            ClazzVO clazzVO = (ClazzVO) objClazz;
                            clazzNameList.add(clazzVO.getName());
                        }
                    }
                }
            }
        }
        //没找到班级时通过专业、年级和方向进行搜索
        if (CollUtil.isEmpty(clazzNameList)) {
            if (StrUtil.isNotBlank(courseMajorCode) && StrUtil.isNotBlank(courseGrade)) {
                for (Object objClazz : clazzMap.values()) {
                    ClazzVO clazzVO = (ClazzVO) objClazz;
                    String clazzMajorCode = clazzVO.getMajorCode();
                    String clazzGrade = clazzVO.getGrade();
                    //通过专业和年级找到班级了
                    if (StrUtil.equalsIgnoreCase(clazzMajorCode, courseMajorCode) && StrUtil.equalsIgnoreCase(clazzGrade, courseGrade)) {
                        clazzNameList.add(clazzVO.getName());
                    }
                }
            }
        }
        return clazzNameList;
    }


    public List<String> getErrorList() {
        return this.errorList;
    }


    public String clearStrData(String name) {
        name = name.replaceAll("（", "(")
                .replaceAll("）", ")");
        String insignWordStr = "(\\r|\\n|\\t)";
        Pattern pattern = Pattern.compile(insignWordStr, Pattern.DOTALL);
        return name.replaceAll(pattern.toString(), "").trim();
    }

    /**
     * 切分班级
     *
     * @param clazzStr
     * @return
     */
    public List<String> splitClazz(String clazzStr) {
        List<String> clazzList = new ArrayList<>();
        if (StrUtil.isBlank(clazzStr)) {
            return clazzList;
        }
        clazzStr = clazzStr.trim();
        String regex = keyProperty.getCourseKeyProperty().getClazzSplitStr();
        if (StrUtil.isBlank(regex)) {
            return clazzList;
        }
        Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
        String[] array = clazzStr.split(pattern.toString());
        if (ArrayUtil.isNotEmpty(array)) {
            for (int i = 0; i < array.length; i++) {
                String clazzName = array[i];
                if (StrUtil.isNotBlank(clazzName)) {
                    clazzList.add(clazzName);
                }
            }
        }
        return clazzList;
    }

    /**
     * 切分教师
     *
     * @param teacherStr
     * @return
     */
    public TeacherVO initTeacherSplit(String teacherStr) {
        TeacherVO teacher = null;
        if (StrUtil.isNotBlank(teacherStr)) {
            teacherStr = teacherStr.trim();
            String regex = keyProperty.getCourseKeyProperty().getCourseTeacherRegStr();
            Pattern p = Pattern.compile(regex);
            Matcher matcher = p.matcher(teacherStr);
            if (matcher.find()) {
                teacher = new TeacherVO();
                teacher.setName(matcher.group(NAME_STR).trim());
                teacher.setCode(matcher.group(CODE_STR).trim());
            }
        }
        return teacher;
    }

    /**
     * 切分课程
     *
     * @param courseStr
     * @return
     */
    public CourseVO initCourseSplit(String courseStr, String nameCodeRegStr) {
        CourseVO courseVO = null;
        if (StrUtil.isNotBlank(courseStr)) {
            courseStr = clearStrData(courseStr);
            Pattern p = Pattern.compile(nameCodeRegStr);
            Matcher matcher = p.matcher(courseStr);
            if (matcher.find()) {
                courseVO = new CourseVO();
                courseVO.setName(matcher.group(NAME_STR).trim());
                courseVO.setCode(matcher.group(CODE_STR).trim());
            }
        }
        return courseVO;
    }

    /**
     * 抽取专业方向的父专业
     *
     * @param majorMap
     * @param mark
     * @return
     */
    public Map<String, Object> extraFx4Major(Map<String, Object> majorMap, String mark, Map<String, Object> majorFxMap) {
        Collection<Object> mapValue = majorMap.values();
        for (Object obj : mapValue) {
            MajorVO majorVO = (MajorVO) obj;
            String typeName = majorVO.getType();
            if (StrUtil.isNotBlank(typeName) && StrUtil.equalsIgnoreCase(typeName, mark)) {
                String code = majorVO.getCode();
                //提取出专业方向号
                MajorFxVO majorFxVO = initParentMajor(code);
                String parentMajorCode = majorFxVO.getParentMajorCode();
                majorFxVO.setName(majorVO.getName());
                majorFxMap.put(majorFxVO.getCode(), majorFxVO);
                Object parentObj = majorMap.get(parentMajorCode);
                if (parentObj != null) {
                    MajorVO parentMajorVo = (MajorVO) parentObj;
                    majorFxVO.setParentMajorName(parentMajorVo.getName());
                }
                majorFxVO.setCollegeName(majorVO.getCollegeName());
                majorFxVO.setCollegeCode(majorVO.getCollegeCode());
                majorFxMap.put(code, majorFxVO);
            }
        }
        //校验下名字相同,代码不同的
        Map<String, String> verifyMap = new HashMap<>();
        for (Object fxObj : majorFxMap.values()) {
            MajorFxVO majorFxVO = (MajorFxVO) fxObj;
            String name = majorFxVO.getName();
            String code = majorFxVO.getCode();
            //从专业表里面删除
            majorMap.remove(code);
            String tmpCode = verifyMap.get(name);
            if (tmpCode == null) {
                verifyMap.put(name, code);
            } else {
                if (!StrUtil.equalsIgnoreCase(tmpCode, code)) {
                    String fxError = "专业方向:[" + name + "]存在多个代码";
                    errorList.add(fxError);
                }
            }
        }
        return majorFxMap;
    }

    /**
     * 专业方向代码解析
     *
     * @param majorCodeStr
     * @return
     */
    private MajorFxVO initParentMajor(String majorCodeStr) {
        MajorFxVO majorFxVO = null;
        if (StrUtil.isNotBlank(majorCodeStr)) {
            majorCodeStr = majorCodeStr.trim();
            String regex = keyProperty.getMajorKeyProperty().getMajorTypeStrReg();
            Pattern p = Pattern.compile(regex);
            Matcher matcher = p.matcher(majorCodeStr);
            if (matcher.find()) {
                majorFxVO = new MajorFxVO();
                majorFxVO.setParentMajorCode(matcher.group(CODE_STR).trim());
                majorFxVO.setCode(majorCodeStr);
            }
        }
        return majorFxVO;
    }

    /**
     * 初始化班级人数
     *
     * @param studentMap
     * @return
     */
    private Map<String, Integer> initClazzNumber(Map<String, Object> studentMap) {
        Map<String, Integer> clazzNumMap = new HashMap<>();
        for (Object obj : studentMap.values()) {
            StudentVO studentVO = (StudentVO) obj;
            String clazzCode = studentVO.getClazzCode();
            Integer count = clazzNumMap.get(clazzCode);
            if (count == null || count == 0) {
                count = 1;
            } else {
                count += 1;
            }
            clazzNumMap.put(clazzCode, count);
        }
        return clazzNumMap;
    }

    /**
     * 重新初始化班级人数
     *
     * @param clazzMap
     * @return
     */
    public Map<String, Object> resetClazzNum(Map<String, Object> clazzMap, Map<String, Object> studentMap) {
        Map<String, Integer> clazzNumMap = initClazzNumber(studentMap);
        for (String codeStr : clazzMap.keySet()) {
            ClazzVO clazzVO = (ClazzVO) clazzMap.get(codeStr);
            String clazzStudentNum = clazzVO.getClazzStudentNum();
            if (StrUtil.isBlank(clazzStudentNum) || clazzStudentNum.equals("0")) {
                Integer clazzNum = clazzNumMap.get(codeStr);
                if (clazzNum != null && clazzNum > 0) {
                    clazzVO.setClazzStudentNum(String.valueOf(clazzNum));
                }
            }
            clazzMap.put(codeStr, clazzVO);
        }
        return clazzMap;
    }


}
